package com.sunducation.wts.datastore

import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.sunducation.wts.datastore.datastore.UserDataStore
import com.sunducation.wts.datastore.datastore.UserPreferenceDataStore
import com.sunducation.wts.datastore.datastore.UserProtoDataStore
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import java.util.*

/*
* 1 添加依赖
2 在 main 文件夹下创建 .proto 文件
3 编写 Serializer
4 编写基础存储工具类
5 举例使用
** 5.1 创建 DataStore 存储工具子类
** 5.2 基本使用
6 混淆

*
* 根据不同的存储需求来实现不同的 proto 文件，然后进行编译, java_package 是生成文件的路径
protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/ds.proto

*
* protoc -I=. --java_out=../java ./ds.proto
*
*
* protoc -I=$SRC_DIR --java_out=$DST_DIR $SRC_DIR/addressbook.proto
* protoc -I=项目路径\app\src\main\proto\ --java_out=项目路径\app\src\main\ 项目路径\app\src\main\proto\user.proto

*
* 我写的：protoc -I=.\datastore\src\main\proto\ --java_out=.\datastore\src\main\java\ .\datastore\src\main\proto\user.proto

*
* 主要优点如下：

允许使用Protocol-Buffers存储键值对或类型化对象
使用Kotlin协程和Flow来异步、一致和事务性地存储数据
DataStore并不被建议用来存储大量复杂的数据，并且无法局部的更新数据，如果有类似的需求可以使用Room组件替代。

*
* Preferences DataStore与SharedPreferences类似，通过键值对存储数据，不保证类型安全。
Proto DataStore通过Protocol-Buffers定义存储数据类型以及结构，保证类型安全。

*
* 两种datastore都demo了一下
*
* bean.user文件夹是自动生成的
* */

private const val TAG = "MainActivity"
class MainActivity : AppCompatActivity() {

    private val dataStores = arrayOf(UserPreferenceDataStore(
        this), UserProtoDataStore(this))

    private var userDataStore: UserDataStore? = dataStores[0]


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        initView()
        initDataStore()
    }

    //1.0 临时写法，最好写在ViewModel里面
    private fun initDataStore(){

        GlobalScope.launch(Dispatchers.Main) {
            dataStores[0].getUsername()
                .collect {
                    if(userDataStore is UserPreferenceDataStore){
                        tv_log.text = it
                    }
                }
        }

        GlobalScope.launch(Dispatchers.Main) {
            dataStores[1].getUsername()
                .collect {
                    if(userDataStore is UserProtoDataStore){
                        tv_log.text = it
                    }
                }
        }

    }

    private fun initView(){
        rg_data_store_type.setOnCheckedChangeListener {
                _, checkedId ->
            userDataStore = if(checkedId == R.id.rb_preferences) dataStores[0] else dataStores[1]
            GlobalScope.launch {
                userDataStore?.getUsername()
                    ?.take(1)
                    ?.collect{
                        tv_log.text = it
                    }
            }
        }
    }

    fun onViewClicked(view: View) {
        when(view.id){
            R.id.bt_set_username -> setUsername()
        }
    }

    //同注释1.0
    private fun setUsername() {
        GlobalScope.launch(Dispatchers.Main) {
            val username = "${userDataStore}danledian${Random().nextInt(1000)}"
            userDataStore?.setUsername(username)
            Toast
                .makeText(applicationContext, getString(R.string.set_success), Toast.LENGTH_SHORT)
                .show()
        }
    }

}